﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Security.Cryptography;

namespace Cutestar_Ticket_Creater
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public class AesUtil
        {
            /// <summary>
            /// AES加密
            /// </summary>
            /// <param name="aesModel"></param>
            /// <returns></returns>
            public static byte[] Encrypt(AesModel aesModel)
            {
                //使用32位密钥
                byte[] key32 = new byte[32];
                //如果我们的密钥不是32为，则自动补全到32位
                byte[] byteKey = Encoding.UTF8.GetBytes(aesModel.Key.PadRight(key32.Length));
                //复制密钥
                Array.Copy(byteKey, key32, key32.Length);

                //使用16位向量
                byte[] iv16 = new byte[16];
                //如果我们的向量不是16为，则自动补全到16位
                byte[] byteIv = Encoding.UTF8.GetBytes(aesModel.IV.PadRight(iv16.Length));
                //复制向量
                Array.Copy(byteIv, iv16, iv16.Length);

                // 创建加密对象,Rijndael 算法
                //Rijndael RijndaelAes = Rijndael.Create();
                RijndaelManaged RijndaelAes = new RijndaelManaged();
                RijndaelAes.Mode = aesModel.Mode;
                RijndaelAes.Padding = aesModel.Padding;
                RijndaelAes.Key = key32;
                RijndaelAes.IV = iv16;
                byte[] result = null;
                try
                {
                    using (MemoryStream ms = new MemoryStream())
                    {
                        using (CryptoStream EncryptStream = new CryptoStream(ms, RijndaelAes.CreateEncryptor(), CryptoStreamMode.Write))
                        {
                            EncryptStream.Write(aesModel.Data, 0, aesModel.Data.Length);
                            EncryptStream.FlushFinalBlock();
                            result = ms.ToArray();
                        }
                    }
                }
                catch { }
                return result;
            }

            /// <summary>
            /// AES解密
            /// </summary>
            /// <param name="aesModel"></param>
            /// <returns></returns>
            public static byte[] Decrypt(AesModel aesModel)
            {
                //使用32位密钥
                byte[] key32 = new byte[32];
                //如果我们的密钥不是32为，则自动补全到32位
                byte[] byteKey = Encoding.UTF8.GetBytes(aesModel.Key.PadRight(key32.Length));
                //复制密钥
                Array.Copy(byteKey, key32, key32.Length);

                //使用16位向量
                byte[] iv16 = new byte[16];
                //如果我们的向量不是16为，则自动补全到16位
                byte[] byteIv = Encoding.UTF8.GetBytes(aesModel.IV.PadRight(iv16.Length));
                //复制向量
                Array.Copy(byteIv, iv16, iv16.Length);

                // 创建解密对象,Rijndael 算法
                //Rijndael RijndaelAes = Rijndael.Create();
                RijndaelManaged RijndaelAes = new RijndaelManaged();
                RijndaelAes.Mode = aesModel.Mode;
                RijndaelAes.Padding = aesModel.Padding;
                RijndaelAes.Key = key32;
                RijndaelAes.IV = iv16;
                byte[] result = null;
                try
                {
                    using (MemoryStream ms = new MemoryStream(aesModel.Data))
                    {
                        using (CryptoStream DecryptStream = new CryptoStream(ms, RijndaelAes.CreateDecryptor(), CryptoStreamMode.Read))
                        {
                            using (MemoryStream msResult = new MemoryStream())
                            {
                                byte[] temp = new byte[1024 * 1024];
                                int len = 0;
                                while ((len = DecryptStream.Read(temp, 0, temp.Length)) > 0)
                                {
                                    msResult.Write(temp, 0, len);
                                }

                                result = msResult.ToArray();
                            }
                        }
                    }
                }
                catch { }
                return result;
            }

            /// <summary>
            /// AES加密字符串
            /// </summary>
            /// <param name="data"></param>
            /// <param name="key"></param>
            /// <param name="iv"></param>
            /// <returns></returns>
            public static string Encrypt(string data, string key, string iv = "")
            {
                byte[] bytes = Encoding.UTF8.GetBytes(data);
                byte[] result = Encrypt(new AesModel
                {
                    Data = bytes,
                    Key = key,
                    IV = iv,
                    Mode = CipherMode.CBC,
                    Padding = PaddingMode.PKCS7
                });
                if (result == null)
                {
                    return "";
                }
                return Convert.ToBase64String(result);
            }

            /// <summary>
            /// AES解密字符串
            /// </summary>
            /// <param name="data"></param>
            /// <param name="key"></param>
            /// <param name="iv"></param>
            /// <returns></returns>
            public static string Decrypt(string data, string key, string iv = "")
            {
                byte[] bytes = Convert.FromBase64String(data);
                byte[] result = Decrypt(new AesModel
                {
                    Data = bytes,
                    Key = key,
                    IV = iv,
                    Mode = CipherMode.CBC,
                    Padding = PaddingMode.PKCS7
                });
                if (result == null)
                {
                    return "";
                }
                return Encoding.UTF8.GetString(result);
            }


            public class AesModel
            {
                /// <summary>
                /// 需要加密/解密的数据
                /// </summary>
                public byte[] Data { get; set; }

                /// <summary>
                /// 密钥
                /// </summary>
                public string Key { get; set; }

                /// <summary>
                /// 向量
                /// </summary>
                public string IV { get; set; }

                /// <summary>
                /// 加密模式
                /// </summary>
                public CipherMode Mode { get; set; }

                /// <summary>
                /// 填充模式
                /// </summary>
                public PaddingMode Padding { get; set; }
            }
        }

        /// <summary>  
        /// MD5加密  
        /// </summary>  
        /// <param name="s">需要加密的字符串</param>  
        /// <returns>加密后的字符串</returns>  
        public static string EncryptMD5(string s)
        {
            MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
            return BitConverter.ToString(md5.ComputeHash(Encoding.Default.GetBytes(s)));
        }
        private void button1_Click(object sender, EventArgs e)
        {
            int length = Convert.ToInt32(0 + textBox1.Text);//生成票号总数
            decimal datanum = 1;//票卡串号
            string data;//中间缓存变量
            string cryptdata;//加密后的单张票码
            string cryptkey;//加密密钥
            string RNG;//一些随机数
            string RNG1;//一些截断的随机数
            decimal RNG2;//跳号判定用随机数
            string insert;//插入在数据前面的一些东西
            data = "";
            insert = textBox2.Text + "";
            if (File.Exists(@"cutestar.key"))
            {


                cryptkey = File.ReadAllText(@"cutestar.key");
                for (int i = 0; i < length; i++)
                {
                    //以下是随机数产生逻辑
                    RNGCryptoServiceProvider csp = new RNGCryptoServiceProvider();
                    byte[] byteCsp = new byte[10];
                    csp.GetBytes(byteCsp);
                    RNG = System.Text.RegularExpressions.Regex.Replace(BitConverter.ToString(byteCsp), @"[^0-9A-F]+", "");
                    RNG1 = RNG[..8];
                    //以下是随机跳号逻辑(考虑到实际情况，取消此功能)

                    //以下是数据加密逻辑

                    cryptdata = AesUtil.Encrypt(insert + datanum + "-" + RNG1, cryptkey);
                    //以下是数据拼接逻辑
                    data = data + cryptdata + System.Environment.NewLine;
                    datanum++;
                }
                File.WriteAllText(@"星萌DB.txt", data);//写入数据库
                MessageBox.Show(
                    length + "个随机票号已生成！" + System.Environment.NewLine +
                    "重新生成将会覆盖之前结果且无法找回！" + System.Environment.NewLine +
                    "请先在软件目录可靠备份“星萌DB.txt”，" + System.Environment.NewLine +
                    "以免后期带来不便！"
                    , "特别提醒！", MessageBoxButtons.OK);
            }
            else
            {
                MessageBox.Show(
                    "请先生成密钥再进行票码生成！"
                    , "特别提醒！", MessageBoxButtons.OK);
            }
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {

        }

        private void label3_Click(object sender, EventArgs e)
        {
            
        }

        private void button2_Click(object sender, EventArgs e)
        {
            string original_text = textBox3.Text;
            if (File.Exists(@"cutestar.key"))
            {
                // Displays a message box asking the user to choose Yes or No.
                if (MessageBox.Show("软件目录已有cutestar.key文件！" + System.Environment.NewLine + "覆盖将无法找回！是否覆盖？", "请注意！",
                   MessageBoxButtons.YesNo) == DialogResult.Yes)
                {
                    decimal lenghth = Encoding.Default.GetByteCount(original_text);
                    if (lenghth < 1)
                    {
                        RNGCryptoServiceProvider csp = new RNGCryptoServiceProvider();
                        byte[] byteCsp = new byte[10];
                        csp.GetBytes(byteCsp);
                        original_text = System.Text.RegularExpressions.Regex.Replace(BitConverter.ToString(byteCsp), @"[^0-9A-F]+", "");
                    }
                    File.WriteAllText(@"cutestar.key", EncryptMD5(original_text));//写入数据库
                    MessageBox.Show(
                            "密钥已写入cutestar.key!" + System.Environment.NewLine + "请妥善保管，此密钥重新生成后原票全部失效！"
                            , "特别提醒！", MessageBoxButtons.OK);
                }
                else
                {

                }
            }
            else
            {
                decimal lenghth = Encoding.Default.GetByteCount(original_text);
                if (lenghth < 1)
                {
                    RNGCryptoServiceProvider csp = new RNGCryptoServiceProvider();
                    byte[] byteCsp = new byte[10];
                    csp.GetBytes(byteCsp);
                    original_text = System.Text.RegularExpressions.Regex.Replace(BitConverter.ToString(byteCsp), @"[^0-9A-F]+", "");
                }
                File.WriteAllText(@"cutestar.key", EncryptMD5(original_text));//写入数据库
                MessageBox.Show(
                        "密钥已写入cutestar.key!" + System.Environment.NewLine + "请妥善保管，此密钥重新生成后原票全部失效！"
                        , "特别提醒！", MessageBoxButtons.OK);
            }

            
        }

        private void button3_Click(object sender, EventArgs e)
        {
            string decrypt_test = textBox4.Text;
            if (File.Exists(@"cutestar.key"))
            {
                string decrypt_key = File.ReadAllText(@"cutestar.key");
                try
                {
                    string output = AesUtil.Decrypt(decrypt_test, decrypt_key);
                    textBox4.Text = output;
                    label5.Text = "票号：" + output.Remove(output.LastIndexOf("-")) + System.Environment.NewLine +
                        "防伪码：" + output.Substring(output.Length - 8, 8);
                }
                catch (Exception)
                {
                    textBox4.Text = "密钥与密文不匹配！";
                }
                
            }
            else
            {
                textBox4.Text = "未检测到密钥文件";
            }
            
        }
    }
}
